﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ToolKit.Mvvm.Helpers;
using ToolKit.Mvvm.Interfaces;

namespace ToolKit.Mvvm
{
    /// <summary>
    /// 模块管理器
    /// </summary>
    public sealed class ModuleManager : IModuleManager
    {
        public string ModuleCatalog { get; set; } = @"./Modules";
        public ConcurrentDictionary<string, Type> ModuleMaps { get; } = new ConcurrentDictionary<string, Type>();
        //public  IList<IModule> Modules { get; } = new List<IModule>();

        public ConcurrentDictionary<string, object> Instances { get; } = new ConcurrentDictionary<string, object>();

        public IModuleManager AddModule<T>()
        {
            Type type = typeof(T);

            if (!ModuleMaps.ContainsKey(type.FullName))
            {
                ModuleMaps.TryAdd(type.FullName, type);
            }

            return this;
        }

        public IModuleManager AddModule(Type type)
        {
            if (!ModuleMaps.ContainsKey(type.FullName))
            {
                ModuleMaps.TryAdd(type.FullName, type);
            }

            return this;
        }


        public IModuleManager InitializeModule()
        {
            //获取所有模块文件的程序集
            var assemblies = FileHelper.GetAssemblies(ModuleCatalog);

            //遍历程序集
            foreach (Assembly assembly in assemblies)
            {
                //获取当前程序集中所有类型
                var definedTypes = assembly.GetTypes();

                //遍历所有类型
                foreach (Type type in definedTypes)
                {
                    //追加模块类到Modules集合
                    if (type.GetInterfaces().Contains(typeof(IModule)))
                        this.AddModule(type);
                }
            }



            //获取所有被标识依赖注入特性的Type
            //List<Type> types = assembly.GetDependenceInjectionTypes();
            //注册这些依赖特性的类型
            //container.Register(types);


            return this;
        }
    }
}
